package vm.machine;

import java.util.ArrayList;
import java.util.List;

public class Main {


    public static void main(String[] args) throws InterruptedException {
        Machine machine = new Machine();
        machine.addRegister("pc",new PCRegister());
        machine.addRegister("ax",new AXRegister());
        machine.addRegister("dx",new DXRegister());
        machine.addRegister("flag",new FlagRegister());


        List<Instruction> instructions = new ArrayList<>();
        /*instructions.add(new LoadInstruction(machine,3));
        instructions.add(new AddInstruction(machine));*/


        //实现函数add(n){n + 1}
       /* instructions.add(new NopInstruction(machine));
        instructions.add(new PushInstruction(machine,3));
        instructions.add(new CallInstruction(machine,5));
        instructions.add(new NopInstruction(machine));
        instructions.add(new NopInstruction(machine));
        instructions.add(new PopInstruction(machine,"dx"));
        instructions.add(new LoadInstruction(machine,"ax",1));
        instructions.add(new AddInstruction(machine,"ax","dx"));*/

         /*f(n){
             if(n == 1){
                 return n;
             }else {
                 return n + f(n-1)
             }
         }*/

        instructions.add(new NopInstruction(machine));
        instructions.add(new PushInstruction(machine,16));//压入返回地址
        instructions.add(new LoadInstruction(machine,"ax",5));//参数n
        instructions.add(new CallInstruction(machine,4));
        //以下指令为函数实现
        instructions.add(new EqualInstuction(machine,"ax",1));
        instructions.add(new JeInstruction(machine,1,10));
        //if-2
        instructions.add(new PushInstruction(machine,"ax"));//压入当前n
        instructions.add(new PushInstruction(machine,12));//压入递归返回地址
        instructions.add(new SubtractInstruction(machine,"ax",1));
        instructions.add(new CallInstruction(machine,4));
        //if-1
        instructions.add(new LoadInstruction(machine,"ax",1));
        instructions.add(new ReturnInstruction(machine));
        //递归返回执行地址
        //result:
        instructions.add(new PopInstruction(machine,"dx"));
        instructions.add(new AddInstruction(machine,"ax","dx"));
        instructions.add(new ReturnInstruction(machine));

        instructions.add(new NopInstruction(machine));//顶层函数调用完，返回地址
        machine.loadInstructiosn(instructions);

        machine.start();
    }
}
